/*
 * httpcachingresolver.cpp
 *
 *  Created on: Oct 8, 2011
 *      Author: anonovermind <anonovermind@gmail.com>
 */

#include "../include/httpcachingresolver.h"
#include <boost/bind.hpp>

namespace Wishmaster2
{
namespace Network
{

HttpCachingResolver::HttpCachingResolver(boost::asio::io_service* service) : m_service(service)
{
	m_resolver = new boost::asio::ip::tcp::resolver(*service);
}

HttpCachingResolver::~HttpCachingResolver()
{
	delete m_resolver;
}

void HttpCachingResolver::resolve(const std::string& host, resolveResultFunction resultCallback)
{
	auto endpoint = m_finished.find(host);
	if(endpoint == m_finished.end())
	{
		doQuery(host);
		m_queries.push_back(Query {host, resultCallback});
	}
	else
	{
		resultCallback(boost::system::error_code(), endpoint->second);
	}
}

void HttpCachingResolver::doQuery(const std::string& host)
{
	boost::asio::ip::tcp::resolver::query query(host, "http"); // FIXME hardcoded
	m_resolver->async_resolve(query, boost::bind(&HttpCachingResolver::resolveResult, this, host,
			boost::asio::placeholders::error, boost::asio::placeholders::iterator));
}

void HttpCachingResolver::resolveResult(const std::string& host, const boost::system::error_code& error,
			boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
{
	if(!error)
		m_finished[host] = endpoint_iterator;
	std::for_each(m_queries.begin(), m_queries.end(), [&] (const Query& q) -> void
			{
				if(q.host == host)
					q.callback(error, endpoint_iterator);
			});
	std::remove_if(m_queries.begin(), m_queries.end(), [&host] (const Query& q) -> bool
			{
				return q.host == host;
			});
}

} /* namespace Network */
} /* namespace Wishmaster2 */
